package com.richinfo.nio.client.handler;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.util.Iterator;
import java.util.Set;

/**
 * 客户端线程类
 * 作用 : 专门接收服务器端的响应
 * 
 * Created by WangXJ
 * 2019-07-11 15:46
 */
public class NioClientHandler implements Runnable {
	
	private Selector selector;

	public NioClientHandler(Selector selector) {
		this.selector = selector;
	}
	
	@Override
	public void run() {
		// 循环等待新接入的连接
		while (true) {
			try {
				// 获取可用的channel数量
				int readyChannels = selector.select();
				// TODO 有待解释
				if (readyChannels == 0) continue;
				// 获取可用的channel集合
				Set<SelectionKey> selectionKeys = selector.selectedKeys();
				Iterator<SelectionKey> iterator = selectionKeys.iterator();
				while (iterator.hasNext()) {
					// 获取当前selectionKey实例
					SelectionKey selectionKey = iterator.next();
					// 把当前selectionKey从set集中移除
					iterator.remove();
					
					// 根据就绪状态，调用对应方法处理业务逻辑
					// 如果是  可读事件
					if (selectionKey.isReadable()) {
						readHandler(selectionKey, selector);
					}
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
	
	/**
	 * 可读事件处理器
	 */
	private void readHandler(SelectionKey selectionKey, Selector selector) throws IOException {
		// 从selectionKey中获取已经就绪的channel
		SocketChannel socketChannel = (SocketChannel) selectionKey.channel();
		// 创建buffer
		ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
		// 循环读取客户端请求信息
		String response = "";
		while (socketChannel.read(byteBuffer) > 0) {
			// 切换buffer为读模式
			byteBuffer.flip();
			// 读取buffer中的内容
			response += Charset.forName("UTF-8").decode(byteBuffer);
			// TODO 将channel再次注册到selector上，监听 可读事件(好像可以省略，有待验证)
			socketChannel.register(selector, SelectionKey.OP_READ);
			// 将客户端发送的请求信息，广播给其他客户端
			if (response.length() > 0) {
				System.out.println(">> " + response);
			}
		}
	}

}
